package com.yangcangclub.api.v1.trade.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.yangcangclub.commons.annotation.*;
import com.yangcangclub.commons.exception.ApolloException;
import com.yangcangclub.commons.result.MessageEnum;
import com.yangcangclub.commons.result.ResultData;
import com.yangcangclub.commons.utils.StringUtil;
import com.yangcangclub.pay.utils.XmlUtil;
import com.yangcangclub.trade.bean.TradeRefund;
import com.yangcangclub.trade.bean.TradeVo;
import com.yangcangclub.trade.bean.UserAddress;
import com.yangcangclub.trade.service.TradeRefundService;
import com.yangcangclub.trade.service.TradeService;
import com.yangcangclub.trade.service.UserAddressService;
import com.yangcangclub.user.component.UserComponent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Controller
@RequestMapping("/yangcangclub/v1/refund")
public class TradeRefundController {
    private static Logger logger = LoggerFactory.getLogger(TradeRefundController.class);

    @Autowired
    TradeRefundService tradeRefundService;
    @Autowired
    UserComponent userComponent;

    /** 申请退款
     * @param user
     * @param tradeId
     * @param productId
     * @param refundType
     * @param applyRefundPrice
     * @param applyRefundReasonType
     * @param applyRefundReason
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/api/apply", method = { RequestMethod.POST })
    @ApolloSecurity(auth = AuthEnum.USER,limit = 50,time = TimeEnum.MINUTE)
    public ResultData apply(@GetUser User user, int tradeId,
                          @RequestParam(required=false,defaultValue = "0")int productId,
                          String refundType,String applyRefundPrice,
                            @RequestParam(required=false,defaultValue = "0")int applyRefundReasonType,
                            @RequestParam(required=false,defaultValue = "")String applyRefundReason){
        ResultData resultData ;
        try {
            //校验
            if(StringUtil.isNotNumber(applyRefundPrice)){
                throw new ApolloException(MessageEnum.ERROR_TRADEREFUND_PRICE);
            }
            //F整单退款G商品退款
            if(!"F".equals(refundType) && !"G".equals(refundType)){
                throw new ApolloException(MessageEnum.ERROR_TRADEREFUND_TYPE);
            }
            tradeRefundService.applyTradeRefund(user.getId(),tradeId,productId,refundType,applyRefundPrice,applyRefundReasonType,applyRefundReason);
            resultData = new ResultData(MessageEnum.SUCCESS);
        }  catch (ApolloException apoEx) {
            resultData=new ResultData(apoEx);
        }catch (Exception e) {
            logger.error(e.getMessage(), e);
            resultData=new ResultData(e);
        }
        return resultData;
    }

    /** 获取申请退款列表
     * @param user
     * @param offset
     * @param limit
     * @param tradeNo
     * @param refundNo
     * @param createDateBegin
     * @param createDateEnd
     * @param status
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/manager/showTradeRefundList")
    @ApolloSecurity(auth = AuthEnum.ADMIN,limit = 50,time = TimeEnum.MINUTE)
    public ResultData tradeRefundList(@GetUser User user,
                                           @RequestParam(required=false,defaultValue = "0")String offset,
                                           @RequestParam(required=false,defaultValue = "10")String limit,
                                         @RequestParam(required=false,defaultValue = "")String tradeNo,
                                         @RequestParam(required=false,defaultValue = "")String refundNo,
                                           String createDateBegin,
                                           String createDateEnd,
                                           String status){
        ResultData resultData ;
        try {
            Map<String,Object> map = Maps.newHashMap();
            //业务
            map.put("tradeNo",StringUtil.isNotEmpty(tradeNo)?tradeNo:"");
            map.put("refundNo",StringUtil.isNotEmpty(refundNo)?refundNo:"");
            map.put("refundOperationStatus",StringUtil.isNotEmpty(status)?status:"");
            if(StringUtil.isNotEmpty(createDateBegin)){
                map.put("createDateBegin",StringUtil.checkDateFormat(createDateBegin)?createDateBegin:"");
            }
            if(StringUtil.isNotEmpty(createDateEnd)){
                map.put("createDateEnd",StringUtil.checkDateFormat(createDateEnd)?createDateEnd:"");
            }
            map.put("sortColumns","create_date desc");
            Map<String, Object> mapResult = tradeRefundService.applyTradeRefundList(Integer.valueOf(offset),Integer.valueOf(limit),map);
            resultData = new ResultData(MessageEnum.SUCCESS,mapResult);
        }  catch (ApolloException apoEx) {
            resultData=new ResultData(apoEx);
        }catch (Exception e) {
            logger.error(e.getMessage(), e);
            resultData=new ResultData(e);
        }
        return resultData;
    }
    @ResponseBody
    @RequestMapping(value = "/manager/showTrade")
    @ApolloSecurity(auth = AuthEnum.ADMIN,limit = 50,time = TimeEnum.MINUTE)
    public ResultData managerShowTrade(@GetUser User user,
                                       int tradeRefundId,
                                       String tradeNo){
        ResultData resultData ;
        try {
            //判断
            if(tradeRefundId<1 || StringUtil.isEmpty(tradeNo)){
                throw new ApolloException(MessageEnum.PARMA_FORMAT_ERROR);
            }
            TradeVo tradeVo = tradeRefundService.getTradeVoByTradeNoAndTradeRefundId(tradeRefundId,tradeNo);
            Map<String,Object> map = Maps.newHashMap();
            Map<String,Object> u = userComponent.getUserInfo(tradeVo.getTradeSummary().getUserId());
            map.put("trade",tradeVo);
            map.put("user",u);
            resultData = new ResultData(MessageEnum.SUCCESS,map);
        }  catch (ApolloException apoEx) {
            resultData=new ResultData(apoEx);
        }catch (Exception e) {
            logger.error(e.getMessage(), e);
            resultData=new ResultData(e);
        }
        return resultData;
    }
    /**更新退款记录状态
     * @param user
     * @param tradeRefundId
     * @param status
     * @param remark
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/manager/updateTradeRefundStatus", method = { RequestMethod.POST })
    @ApolloSecurity(auth = AuthEnum.ADMIN,limit = 50,time = TimeEnum.MINUTE)
    public ResultData updateTradeRefundStatus(@GetUser User user,int tradeRefundId, String status,
                                                     @RequestParam(value="remark",defaultValue = "")String remark ){
        ResultData resultData ;
        try {
            if(tradeRefundId <= 0){
                throw new ApolloException(MessageEnum.PARMA_FORMAT_ERROR);
            }
            boolean b = tradeRefundService.updateTradeRefundOperationStatus(user.getId(),user.getName(),tradeRefundId,status,remark);
            if(b){
                resultData = new ResultData(MessageEnum.SUCCESS);
            }else{
                resultData = new ResultData(MessageEnum.FAILURE);
            }
        }  catch (ApolloException apoEx) {
            resultData=new ResultData(apoEx);
        }catch (Exception e) {
            logger.error(e.getMessage(), e);
            resultData=new ResultData(e);
        }
        return resultData;
    }
    @ResponseBody
    @RequestMapping(value = "/manager/tradeRefund", method = { RequestMethod.POST })
    @ApolloSecurity(auth = AuthEnum.ADMIN,limit = 50,time = TimeEnum.MINUTE)
    public ResultData tradeRefund(@GetUser User user,int tradeRefundId, String refundPrice,
                                  @RequestParam(value="refundAccount",defaultValue = "")String refundAccount,
                                  @RequestParam(value="refundRemark",defaultValue = "")String refundRemark ){
        ResultData resultData ;
        try {
            if(tradeRefundId <= 0){
                throw new ApolloException(MessageEnum.PARMA_FORMAT_ERROR);
            }
            Map map = tradeRefundService.tradeRefund(tradeRefundId,refundPrice,refundRemark,refundAccount);
            if(!map.isEmpty() && (boolean)map.get("result")){
                resultData = new ResultData(MessageEnum.SUCCESS);
            }else{
                resultData = new ResultData(MessageEnum.FAILURE,map.get("errorMsg"));
            }
        }  catch (ApolloException apoEx) {
            resultData=new ResultData(apoEx);
        }catch (Exception e) {
            logger.error(e.getMessage(), e);
            resultData=new ResultData(e);
        }
        return resultData;
    }
}
